#include <stdio.h>
#include <stdlib.h>
#include "kernel_list.h"
// 链表节点
typedef struct
{
    int data;
    struct list_head list; // 定义小结构体
} ListNode;

// 初始化队列
typedef struct
{
    // head 表示内核链表的链表头
    ListNode *front, *rear, *head; // 初始化队首，队尾
    int que_size;                  // 初始化队列长度
} LinkedListQueue;

// 初始化链表节点
ListNode *create_list_node(int data)
{
    ListNode *n = malloc(sizeof(LinkedListQueue));
    n->data = data;
    INIT_LIST_HEAD(&n->list); // 初始化小结构体

    return n;
}

// 初始化队列
LinkedListQueue *new_linked_list_queue()
{
    LinkedListQueue *q = malloc(sizeof(LinkedListQueue));
    q->head = create_list_node(-2);
    q->front = NULL;
    q->rear = NULL;
    q->que_size = 0;

    return q;
}
// 析构函数
void del_linked_list_queue(LinkedListQueue *q)
{
    // 释放所有节点
    /*
    参数解释：
            p 是当前节点的指针。
            n 是临时指针，用于保存下一个节点的地址。
            &q->head->list 是链表的头指针。
            list 是 ListNode 结构体中嵌入的 struct list_head 成员的名称。
    */
    ListNode *p, *n;
    list_for_each_entry_safe(p, n, &q->head->list, list)
    {
        list_del(&p->list); // 删除小结构体
        free(p);            // 删除大结构体
    }
    free(q->head);
    // 释放 q 结构体
    free(q);
}

/* 获取队列的长度 */
int size(LinkedListQueue *queue)
{
    return queue->que_size;
}

/* 判断队列是否为空 */
int empty(LinkedListQueue *queue)
{
    return (size(queue) == 0);
}

// 入队
void push(LinkedListQueue *q, int data)
{

    ListNode *n = create_list_node(data);
    // 先进新出 尾插法
    list_add_tail(&n->list, &q->head->list); // 传入插入位置的地址和首元素地址

    if (empty(q)) // 第一次入队，队首和队尾是同一个元素
    {
        q->front = n;
    }
    q->rear = n;

    q->que_size++;
}
// 访问队首元素
int peek(LinkedListQueue *q)
{
    if (empty(q))
    {
        return -1;
    }

    return q->front->data;
}
// 出队
int pop(LinkedListQueue *q)
{
    if (empty(q))
    {
        return -1;
    }
    int data = peek(q);
    // 旧的队首
    ListNode *n = q->front;
    // 删掉队首内部的小结构体节点
    list_del(&q->front->list);

    free(n);
    // 更新队首
    q->front = list_entry(q->head->list.next, ListNode, list);
    q->que_size--;

    return data;
}

// 打印队列
void print_linked_list_queue(LinkedListQueue *q)
{
    if (empty(q))
    {
        return -1;
    }
    int *arr = malloc(sizeof(int) * q->que_size);
    // 拷贝链表中的数据到数组
    /*
    list_for_each_entry 宏：
                    用于遍历链表.
                    pos 是当前节点的指针。
                    &q->head->list 是链表的头指针。
                    list 是 ListNode 结构体中嵌入的 struct list_head 成员的名称。
    */
    int i = 0;
    ListNode *pos;
    list_for_each_entry(pos, &q->head->list, list)
    {
        printf("%d \n", pos->data);// 打印当前节点的数据
        arr[i++] = pos->data;      // 将数据拷贝到数组
    }

    for (int j = 0; j < i; j++)
    {
        printf("%d ", arr[j]);      // 打印数组中的数据
    }
    printf("\n");

    free(arr);
}

int main(int argc, char const *argv[])
{
    LinkedListQueue *q = new_linked_list_queue();
    push(q, 1);
    push(q, 2);
    push(q, 3);
    push(q, 4);
    push(q, 5);
    push(q, 6);

    // printf("%d \n", peek(q));

    print_linked_list_queue(q);

    // printf("%d \n", pop(q));
    // printf("%d \n", pop(q));
    // printf("%d \n", pop(q));
    // printf("%d \n", pop(q));
    // printf("%d \n", pop(q));

    // delLinkedListQueue(q);
    return 0;
}
